package com.read.controller;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.read.service.BookService;
import com.read.resp.BaseResp;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * @ClassName ClientAController
 * @Description TODO
 * @Author young
 * @Date 2022-10-31 16:20
 * @Version 1.0
 **/
@Api(tags = "图书查询接口")
@RequestMapping("/book")
@RestController
//该注解含义: 当配置文件更改后,本地也会动态刷新配置文件内容
@RefreshScope
public class BookController {

    @Value("${server.port}")
    private String port;
    @Value("${student.name}")
    private String name;
    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    BookService bookService;

    @RequestMapping("/testPort")
    public String testPort(){
        redisTemplate.opsForValue().set("msg","hello");
        return port+name;
    }

    @HystrixCommand(fallbackMethod = "getBookByBookIdFallback",commandProperties = {
            //线程隔离策略
            @HystrixProperty(name = "execution.isolation.strategy",value = "THREAD"),
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000"),
            //开启断路器
            @HystrixProperty(name = "circuitBreaker.enabled",value = "true"),
            //配置失败阈值的总请求数，达到失败多少次时，直接走熔断方法
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),
            //请求总数的失败率达到%多少时
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "50"),
            //断路器open状态后，多长时间拒绝请求，或者多长时间变为half open状态
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "5000"),
    })
    @ApiOperation(value = "根据bookId查询图书基本信息(图书名称, url, 热度)")
    @GetMapping("/getBookByBookId")
    public BaseResp getBookByBookId(@RequestParam("bookId") String bookId){
        return bookService.getBookByBookId(bookId);
    }


    @HystrixCommand(fallbackMethod = "getBookDetailsByBoodIdFallback",commandProperties = {
            //线程隔离策略
            @HystrixProperty(name = "execution.isolation.strategy",value = "THREAD"),
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000"),
            //开启断路器
            @HystrixProperty(name = "circuitBreaker.enabled",value = "true"),
            //配置失败阈值的总请求数，达到失败多少次时，直接走熔断方法
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),
            //请求总数的失败率达到%多少时
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "50"),
            //断路器open状态后，多长时间拒绝请求，或者多长时间变为half open状态
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "5000"),
    })
    @ApiOperation(value = "根据bookId查询图书详情")
    @GetMapping("/getBookDetailsByBoodId")
    public BaseResp getBookDetailsByBoodId(@RequestParam("bookId") String bookId){
        return bookService.getBookDetailsByBoodId(bookId);
    }


    /**
     *当前服务被其他服务 调用时,出现异常要执行的熔断方法
     */
    //getBookByBookId方法,触发熔断后要执行的方法  参数和返回值必须与原方法一致
    public BaseResp getBookByBookIdFallback(@RequestParam("bookId") String bookId){
        return new BaseResp().Error("查询图书基本信息出现异常,触发熔断!");
    }

    //getBookDetailsByBoodId方法,触发熔断后要执行的方法  参数和返回值必须与原方法一致
    public BaseResp getBookDetailsByBoodIdFallback(@RequestParam("bookId") String bookId){
        return new BaseResp().Error("查询图书详情出现异常,触发熔断!");
    }

}
